Estas técnicas se basan en la idea de envolver los objetos dentro de volúmenes para los que sea fácil calcular las colisiones, si hay colisiión entre estos volumenes entonces se puede ir detallando gradualmente el nivel de las colisiones, en caso contrario no es necesario hacer ningún cálculo más.
Las colisiones que se considerarán en este trabajo se discutieron en clase y son las siguientes:
Dispositivo Patriot: Este dispositivo cuenta con seis grados de libertad, es decir, proporciona información sobre su posición bajo seis parámmetros significativos distintos.
El dispositivo cuenta con una pequeña base cuadrada. En esta base se encuentra el origen de su sistema coordenado, es decir, la información que arroja el dispositivo es en base a la ubicación de esta base.
También cuenta con una pequeña pluma con un botón. La posición de la pluma respecto a la base cuadrada y su inclinación son los datos que nos arroja el dispositivo: su posición en x,y,z, así como los cosenos directores de la inclinación de la pluma con cada eje. El botón tiene los estados encendido y apagado (1 y 0).
Según el manual, se puede especificar el formato de salida de los datos, así como las unidades deseadas. Se trabajará con el parámetro "P" que devuelve los datos en formato simple.
El cuadricóptero puede rotar en todas direcciones, por lo que delimitarlo por una esfera que lo cubra completamente es una buena idea para poder detectar las colisiones de este objeto.
La colisión enttre esferas es más barata, por esta razón las columnas serán encerradas por esferas para verificar una primera colisión Esfera-Esfera, en caso que se cumpla esta colisión se verificará la colisón Caja-Esfera.
Para el uso del dispositivo Patriot se usará un cilindro que indicará la posición y dirección de un rayo. Para saber si el rayo apunta correctamente a la esfera central del cuadricóptero se usará la prueba Esfera-Rayo. En caso de que se detecte una colisión, la esfera del cuadricóptero cambiara de color y hasta ese momento se podrá atrapar con el dispositivo Patriot para que se mueva con él.
Luego de realizar algunas pruebas con el dispositivo, se decidió que el origen del sistema de coordenadas del dispositivo coincidiera con el del mundo virtual una vez que este sea seleccionado. El orden de las coordenadas se cambió ya que el dispositivo retorna los valores de x,y,z; que equivaldrían dentro del mundo virtual a x,z,y, respectivamente. La orientación del cubo del dispositivo debe orientarse correctammente para obtener los movimientos deseados, en caso que la orienntación sea incorrecta, el cuadricóptero se moverá de forma distinta.
Se implementarán métodos para la detección de colisiones antes mencionadas. Los objetos cajas estarán fijos, el cuadricóptero se moverá y su posición será almacenada en todo momento como el centro de su esfera, y finalmente el cilindro que define el rayo rotará pero su punto de referencia se mantendrá fijo.
Cada vez que el cuadricóptero desee cambiar su posición, se verificarán las colisiones, en caso que no exista colisión alguna, el cuadricóptero será dibujado en la nueva posición, pero de haber colisión el cuadricóptero permanecerá en su posición actual.
ptracker->UsbConnect( 0x0f44, 0xef12, 0x02, 0x82 );
Una vez establecida la conexión se debe configurar el disporitivo en aspecto como lo son las unidades,
el formato de lecture y fijar los puntos de referencia de acuerdo a nuestro mundo virtual. Esto se logra mediante los
siguientes comandos:
/* unidades */
ptracker->WriteTrkData((void*) "u1\r", 3 );
/* modo binario */
ptracker->WriteTrkData((void *) "f1\r", 3 );
/* fomato de entrada */
ptracker->WriteTrkData((void *) "o1,2,4,6,10\r", 12 );
ptracker->WriteTrkData((void *)"\x12\x31\r",3);
memset(command,0,100);
ptracker->WriteTrkData((void *)"r1\r",3);
sprintf(command,"a1,%g,%g,%g,%g,%g,%g,%g,%g,%g\r", 0.0,0.0,0.0, 20.0,0.0,0.0, 0.0,20.0,0.0 );
ptracker->WriteTrkData( (void *)command, strlen(command) );
Una vez que se tiene la conexión se crea un método Patriot() en el que se recuperan los del dispositivo datos mediante los comandos:
ptracker->WriteTrkData( (void *)"p", 1); En donde se especifíca el formato de salida "p".
ptracker->ReadTrkData( (void*)buf, 100); Que retorna los valores y los almacena en un buffer buf defindo previamente.
Se utilzarán los datos de la posición x,y,z; los cosenos directores coon cada eje y el estado del botón (click). El uso de estos datos se especificará más adelante.
Para el manejo de las colisiones se declararon estrcturas que facilitan su implementación, una estructura CAJA con los valores del punto máximo y mínimo de la caja; una estructura ESFERA con el centro y radio; y una estructura RAYO con el punto de referencia del rayo y su vector dirección unitario. El rayo será representado por una línea.
Una vez realzada la conexión con el Patriot, este controla la dirección del cilindro Rayo, la dirección tomada es la que indican los cosenos
directores, esta dirección por definición es unitaria. La posición tomada es relativa a la posición en la que se tomó el cuadricóptero
por primera vez. Cuando el rayo choca con la esfera del cuadricóptero, esta se pinta de rojo y si se aprieta
el botón del dispositivo Patriot, se activa una bandera llamada control que cede el control del cuadricóptero al Patriot. El fragmento
de código que hace lo anterior se muestra a continuación:
click = pFlag[0];
angsPat[0] = pData[6]; //Coseno director de x
angsPat[1] = -pData[8]; //Coseno director de y
angsPat[2] = pData[7]; //Coseno director de z
if( clAnt==0 && click==1 && colisionEsferaRayo()){
control = true;
referencia.x = pData[0];
referencia.y = -pData[2];
referencia.z = pData[1];
}
if(control){
posPat[0] = pData[0]-referencia.x;
posPat[1] = -pData[2]-referencia.y;
posPat[2] = pData[1]-referencia.z;
esf_cuad.centro.y = p.y + ( 0.1*posPat[1] - referencia.y );
esf_cuad.centro.z = p.z + ( 0.1*posPat[2] - referencia.z );*/
esf_cuad.centro.x = 0.2*posPat[0];
esf_cuad.centro.y = 0.2*posPat[1] + 10;
esf_cuad.centro.z = 0.2*posPat[2];
if(click==0)
control = false;
}else{
rayo.dir.x = angsPat[1];
rayo.dir.y = angsPat[2];
rayo.dir.z = angsPat[0];
}
Ahora se verifican las colisiones y si no hay ninguna el cuadricóptero se mueve según los movimientos del Patriot.
Se declaran métodos que verifican las colisiones en orden de
la manera siguiente:
if (colisionMundo()){
esf_cuad.centro = p;
}else if( colisionConEsfera( & esf_col1)){
if(colisionCajaEsfera(&col1))
esf_cuad.centro = p;
}else if(colisionConEsfera( & esf_col2) )
if(colisionCajaEsfera(&col2))
esf_cuad.centro = p;
Los controles referidos al manejo del cuadricóptero, la iluminación y la posición de la cámara se mantienen igual que en la tarea anterior.
Estos son los detalles a grandes rasgos de la implementación. Por último se agregan un par de imágenes con diferente perspectiva y el link de descarga del código fuente del programa:
Mecate Zambrano Miriam. Interacción con Objetos Deformables. Tesis de maestría, CINVESTAV Departamento de Computación, México, D.F., Noviembre 2008.
Alken, Inc. d/b/a Polhemus. PATRIOT USER MANUAL., Colchester, Vermont, U.S.A., Junio 2012.